﻿Imports System.IO
Imports System.Text.Encoding

Namespace Pop.Api.Util

    ''' <summary>
    ''' 文件元数据。
    ''' 可以使用以下几种构造方法：
    ''' 本地路径：new FileItem("C:/temp.jpg");
    ''' 本地文件：new FileItem(new FileInfo("C:/temp.jpg"));
    ''' 字节流：new FileItem("abc.jpg", bytes);
    ''' </summary>
    Public Class FileItem
        Private fileName As String
        Private mimeType As String
        Private content As Byte()
        Private fileInfo As FileInfo

        ''' <summary>
        ''' 基于本地文件的构造器。
        ''' </summary>
        ''' <param name="fileInfo">本地文件</param>
        Public Sub New(ByVal fileInfo As FileInfo)
            If fileInfo Is Nothing OrElse Not fileInfo.Exists Then
                Throw New ArgumentException("fileInfo is null or not exists!")
            End If
            Me.fileInfo = fileInfo
        End Sub

        ''' <summary>
        ''' 基于本地文件全路径的构造器。
        ''' </summary>
        ''' <param name="filePath">本地文件全路径</param>
        Public Sub New(ByVal filePath As String)
            Me.New(New FileInfo(filePath))
        End Sub

        ''' <summary>
        ''' 基于文件名和字节流的构造器。
        ''' </summary>
        ''' <param name="fileName">文件名称（服务端持久化字节流到磁盘时的文件名）</param>
        ''' <param name="content">文件字节流</param>
        Public Sub New(ByVal fileName As String, ByVal content As Byte())
            If String.IsNullOrEmpty(fileName) Then
                Throw New ArgumentNullException("fileName")
            End If
            If content Is Nothing OrElse content.Length = 0 Then
                Throw New ArgumentNullException("content")
            End If

            Me.fileName = fileName
            Me.content = content
        End Sub

        ''' <summary>
        ''' 基于文件名、字节流和媒体类型的构造器。
        ''' </summary>
        ''' <param name="fileName">文件名（服务端持久化字节流到磁盘时的文件名）</param>
        ''' <param name="content">文件字节流</param>
        ''' <param name="mimeType">媒体类型</param>
        Public Sub New(ByVal fileName As String, ByVal content As Byte(), ByVal mimeType As String)
            Me.New(fileName, content)
            If String.IsNullOrEmpty(mimeType) Then
                Throw New ArgumentNullException("mimeType")
            End If
            Me.mimeType = mimeType
        End Sub

#Region "GetFileExtension"

        ''' <summary>
        ''' 获取文件的真实媒体类型。目前只支持JPG, GIF, PNG, BMP四种图片文件。
        ''' </summary>
        ''' <param name="fileData">文件字节流</param>
        ''' <returns>媒体类型</returns>
        Public Shared Function GetMimeType(ByVal fileData As Byte()) As String
            Dim suffix As String = GetFileSuffix(fileData)
            Dim mimeType As String

            Select Case suffix
                Case "JPG"
                    mimeType = "image/jpeg"
                    Exit Select
                Case "GIF"
                    mimeType = "image/gif"
                    Exit Select
                Case "PNG"
                    mimeType = "image/png"
                    Exit Select
                Case "BMP"
                    mimeType = "image/bmp"
                    Exit Select
                Case Else
                    mimeType = "application/octet-stream"
                    Exit Select
            End Select

            Return mimeType
        End Function

        ''' <summary>
        ''' 获取文件的真实后缀名。目前只支持JPG, GIF, PNG, BMP四种图片文件。
        ''' </summary>
        ''' <param name="fileData">文件字节流</param>
        ''' <returns>JPG, GIF, PNG or null</returns>
        Public Shared Function GetFileSuffix(ByVal fileData As Byte()) As String
            If fileData Is Nothing OrElse fileData.Length < 10 Then
                Return Nothing
            End If
            If [Default].GetChars(fileData, 0, 3) = "GIF" Then
                Return "GIF"
            ElseIf [Default].GetChars(fileData, 1, 3) = "PNG" Then
                Return "PNG"
            ElseIf [Default].GetChars(fileData, 6, 4) = "JFIF" Then
                Return "JPG"

            ElseIf [Default].GetChars(fileData, 0, 2) = "BM" Then
                Return "BMP"
            Else
                Return Nothing
            End If
        End Function

#End Region

        Public Function GetFileName() As String
            If Me.fileName Is Nothing AndAlso Me.fileInfo IsNot Nothing AndAlso Me.fileInfo.Exists Then
                Me.fileName = Me.fileInfo.FullName
            End If
            Return Me.fileName
        End Function

        Public Function GetMimeType() As String
            If Me.mimeType Is Nothing Then
                'Me.mimeType = TopUtils.GetMimeType(GetContent())
            End If
            Return Me.mimeType
        End Function

        Public Function GetContent() As Byte()
            If Me.content Is Nothing AndAlso Me.fileInfo IsNot Nothing AndAlso Me.fileInfo.Exists Then
                Using fileStream As System.IO.Stream = Me.fileInfo.OpenRead()
                    Me.content = New Byte(fileStream.Length - 1) {}
                    fileStream.Read(content, 0, content.Length)
                End Using
            End If

            Return Me.content
        End Function

    End Class

End Namespace